home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xnetbris.00 / xnetbris / chris.c < prev    next >
C/C++ Source or Header  |  1995-09-19  |  8KB  |  317 lines

  1. /*
  2.    This is an automated robot called chris.  It randomly plays one of its cards
  3.    Copyright (C) 1995 Brendan Bartlett
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <signal.h>
  23. #include <stdlib.h>
  24. #include <sys/types.h>
  25. #include <sys/time.h>
  26. #include <sys/socket.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <netdb.h>
  30. #include <unistd.h>
  31. #include <sys/types.h>
  32. #include <sys/uio.h>
  33. #include <time.h>
  34.  
  35. #include "brisk.h"
  36.  
  37. static int server_fd;
  38. static int numplayers;
  39. static int play_type;
  40. static int my_number;                /* which player number this client is */
  41.  
  42. static struct card brisk;
  43. static struct card hand[3];                             /* This is an array with the current cards in this players hand */
  44.  
  45. static int get_card(int);                                 /* reads a new card from the server */
  46. static void play_brisk(void);
  47. static void update_cards(void);             /* some sort of change to the hand -- tell the user */
  48. static int give_score(int, char *);
  49. static int randnum;
  50.  
  51. int handler(int signum);
  52. int start_client(char * hostname, int port);
  53. void main(int, char *[]);
  54.  
  55.  
  56. int handler(int signum)
  57. {
  58.   fprintf(stderr, "got SIGPIPE, client cleaning..\n");
  59.   
  60.   close(server_fd);
  61.   exit(0);
  62. }
  63.  
  64. void main(int argc, char *argv[])
  65. {
  66.   int port = 10000;
  67.   struct packet p;
  68.   int i;
  69.  
  70.   signal(SIGPIPE, handler);
  71.  
  72.   if(argc == 1)
  73.     {
  74.       printf("usage: %s <hostname> <port>\n", argv[0]);
  75.       printf(" hostname is the name where the SERVER is running.\n");
  76.       printf(" port is an optional setting to connect to the server.\n");
  77.       exit(0);
  78.     }
  79.  
  80.   if(argc == 3)
  81.     port = atoi(argv[2]);
  82.  
  83.   if(!start_client(argv[1], port))
  84.     {
  85.       printf("cannot connect to server '%s'\n", argv[1]);
  86.       exit(0);
  87.     }
  88.  
  89.  
  90.   /* Read in our hand from the server */
  91.  
  92.  
  93.   for(i = 0; i < 3; i++)
  94.     {
  95.       get_card(i);
  96.       printf(" %d %d \t", hand[i].suit, hand[i].weight);
  97.     }
  98.  
  99.   /* Read in the brisk from the server */
  100.  
  101.   read(server_fd, &p, sizeof(struct packet));
  102.  
  103.   if(p.type != MOVE_TYPE || p.data.move.player != 5)
  104.     {
  105.       fprintf(stderr, "server did not send the brisk card!\n");
  106.       exit(0);
  107.     }
  108.   
  109.   memcpy(&brisk, &p.data.move.play_card, sizeof(struct card));
  110.   printf("\nbrisk: %d %d\n", brisk.suit, brisk.weight);
  111.   
  112.   printf("\n");
  113.   play_brisk();
  114.  
  115. }
  116. /*
  117.  * This routine will read from the server for a packet of MOVE_TYPE (or DEAL_TYPE) and will fill in the
  118.  * given card in the hand[] array.
  119.  *
  120.  * If the packet is of type DEAL_TYPE, the argument 'card' is ignored and the suggested value in the
  121.  * packet is used instead.
  122.  *
  123.  * Returns 0 on failure
  124.  *         1 on success 
  125.  */
  126. static int get_card(int card)
  127. {
  128.   struct packet p;
  129.   
  130.   read(server_fd, &p, sizeof(struct packet));
  131.  
  132.   if( (p.type != MOVE_TYPE) && (p.type != DEAL_TYPE) )
  133.     {
  134.       fprintf(stderr, "FATAL ERROR: MOVE_TYPE or DEAL_TYPE expected!\n");
  135.       return 0;
  136.     }
  137.  
  138.   if(p.type == DEAL_TYPE)
  139.     memcpy(&hand[p.data.deal.rec_place], &p.data.deal.deal_card, sizeof(struct card));
  140.   else
  141.     memcpy(&hand[card], &p.data.move.play_card, sizeof(struct card));
  142.  
  143.   return 1;
  144. }
  145.  
  146. /* *
  147.  * This updates the cards that the user sees on the scren.
  148.  *
  149.  */
  150. static void update_cards(void)
  151. {
  152.   int i;
  153.  
  154.   for(i = 0; i < 3; i++)
  155.     printf("%d %d \t", hand[i].suit, hand[i].weight);
  156.   
  157.   printf("\n");
  158. }
  159.  
  160. static void play_brisk(void)
  161. {
  162.   struct packet in, out;
  163.   srand(time(NULL));
  164.  
  165.   while(1)
  166.     {
  167.       read(server_fd, &in, sizeof(struct packet));
  168.  
  169.       switch(in.type)
  170.     {
  171.     case LAST_HAND:
  172.       printf("Entering the last 3 hands..\n");
  173.  
  174.       break;
  175.     case END_GAME:
  176.       printf("That's the end of the game!\n");
  177.  
  178.       printf("Final Scores: %d for you, %d for the other %s\n",
  179.          give_score(0, in.data.score.scores),
  180.          give_score(1, in.data.score.scores), (play_type == CHAOS) ? "player" : "team");
  181.  
  182.       close(server_fd);
  183.       exit(0);
  184.     case MESSAGE_TYPE:
  185.       printf("message: [%s]\n", in.data.message.string);
  186.       break;
  187.     case MOVE_TYPE:
  188.       printf("player %d played card %d %d\n", in.data.move.player, in.data.move.play_card.suit, in.data.move.play_card.weight);
  189.       break;
  190.     case SCORE_UPDATE:
  191.       printf("\nplayer %d won last hand!\n", in.data.score.lastwin);
  192.       printf("scores: %d %d\n", in.data.score.scores[0], in.data.score.scores[1]);
  193.  
  194.       in.type = OK;
  195.  
  196.       write(server_fd, &in, sizeof(struct packet));
  197.  
  198.       break;
  199.     case DEAL_TYPE:
  200.       memcpy(&hand[in.data.deal.rec_place], &in.data.deal.deal_card, sizeof(struct card));
  201.       break;
  202.     case INFORM_TYPE:
  203.       printf("server send INFORM_TYPE. Not at start of game\n");
  204.       break;
  205.     case MOVE_EXPECTED:
  206.       if(in.data.move.player != my_number)
  207.         break;
  208.  
  209.       out.type = MOVE_TYPE;
  210.       out.data.move.player = my_number;
  211.  
  212.       do
  213.         {
  214.  
  215.  
  216.           /* Chris randomly chooses a card from his hand.  
  217.            * In the final two hands a player has less then the normal 
  218.            * three cards, so a -1 is used to repersent the non-existant card.
  219.            * Chris checks for it and tries again if he chooses it.
  220.           */
  221.  
  222.           while(1)
  223.         {
  224.           randnum = rand() % 3;
  225.  
  226.           if ((hand[randnum].suit != -1) && (hand[randnum].weight != -1))
  227.             {
  228.               out.data.move.play_card.suit = hand[randnum].suit;
  229.               out.data.move.play_card.weight = hand[randnum].weight;
  230.               printf("%d %d\n", hand[randnum].suit, hand[randnum].weight);
  231.               break;
  232.             }
  233.         }
  234.  
  235.           write(server_fd, &out, sizeof(struct packet));
  236.  
  237.           read(server_fd, &in, sizeof(struct packet));
  238.         
  239.           if(in.type == ILLEGAL_MOVE)
  240.         printf("illegal card %d %d\n", out.data.move.play_card.suit, out.data.move.play_card.weight);
  241.         }
  242.       while(in.type == ILLEGAL_MOVE);
  243.  
  244.       hand[in.data.ok.cardpos].suit = -1;
  245.       hand[in.data.ok.cardpos].weight = -1;
  246.     }
  247.     }
  248. }
  249.  
  250. /*
  251.  * Given the packet 'p' return the score of 'who', where
  252.  * who is 0 for yourself and 1 for the other player/team
  253.  */
  254. static int give_score(int who, char *scores)
  255. {
  256.   char scoretab[] = { 0, 1, 0, 1 };
  257.  
  258.   if(who == 0)
  259.     return scores[scoretab[my_number]];
  260.   else
  261.     return scores[! scoretab[my_number]];
  262.  
  263. }      
  264.  
  265. int start_client(char *hostname, int port)
  266. {
  267.   struct sockaddr_in addr;
  268.   struct protoent *proto;
  269.   struct hostent *host;
  270.   struct packet p;
  271.  
  272.   proto = getprotobyname("tcp");
  273.   if(!proto)
  274.     {
  275.       printf("tcp not supported here.\n");
  276.       return 0;
  277.     }
  278.  
  279.   host = gethostbyname(hostname);
  280.  
  281.   if(!host)
  282.     {
  283.       printf("cannot find host '%s'\n", host);
  284.       return 0;
  285.     }
  286.  
  287.   addr.sin_family = AF_INET;
  288.   addr.sin_port = htons(port);
  289.   addr.sin_addr.s_addr = inet_addr(hostname);
  290.   memcpy((char *)&addr.sin_addr, (char *)(*host->h_addr_list), host->h_length);
  291.   server_fd = socket(PF_INET, SOCK_STREAM, proto->p_proto);
  292.   if(server_fd == -1)
  293.     {
  294.       perror("socket");
  295.       return 0;
  296.     }
  297.  
  298.   printf("Attemping to connect to port %i of server %s.\n", port, hostname);
  299.   
  300.   if(connect(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
  301.     {
  302.       perror("connect");
  303.       return 0;
  304.     }
  305.  
  306.   read(server_fd, &p, sizeof(struct packet));
  307.   
  308.   printf("# players %d (robot:Chris).  I am player # %d\n", p.data.inform.numplayers, p.data.inform.yournumber);
  309.  
  310.   numplayers = p.data.inform.numplayers;
  311.   play_type = p.data.inform.play_type;
  312.   my_number = p.data.inform.yournumber;
  313.  
  314.   return 1;
  315. }
  316.  
  317.